package com.whatech.mall.user.controller;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.whatech.mall.common.utils.MD5Utils;
import com.whatech.mall.user.model.dto.UserDTO;
import com.whatech.mall.user.model.entity.User;
import com.whatech.mall.user.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;

/**
 * 用户Controller。
 */
@RestController
@RequestMapping("/user")
@Slf4j
// 开启动态刷新配置
@RefreshScope
public class UserController {

    @Autowired
    private UserService userService;
    @Value("${user.info}")
    private String info;

    /**
     * 根据ID查询用户信息
     *
     * @param id 用户ID
     * @return UserDTO
     */
    @GetMapping("/query/{id}")
    @SentinelResource(value = "user-query-resource",
            blockHandler = "queryBlockHandler",
            fallback = "queryFallback")
    public UserDTO query(@PathVariable Long id) {
        log.info("call UserController.query(), id = {}", id);

        User user = userService.getById(id);
        if (user == null) {
            return null;
        }

        UserDTO userDTO = new UserDTO();
        BeanUtils.copyProperties(user, userDTO);

        return userDTO;
    }

    // 熔断处理
    public UserDTO queryBlockHandler(Long id, BlockException e) {
        log.warn("UserController.query() block.", e);
        UserDTO userDTO = new UserDTO();
        userDTO.setId(id);
        return userDTO;
    }

    // 降级处理
    public UserDTO queryFallback(Long id, Throwable t) {
        log.warn("UserController.query() fallback.", t);
        UserDTO userDTO = new UserDTO();
        userDTO.setId(id);
        return userDTO;
    }

    /**
     * 查询用户列表
     *
     * @return List<UserDTO>
     */
    @GetMapping("/list")
    @SentinelResource(value = "user-list-resource",
            blockHandler = "listBlockHandler",
            blockHandlerClass = UserControllerBlockHandlerClass.class,
            fallback = "listFallback",
            fallbackClass = UserControllerFallbackClass.class)
    public List<UserDTO> list() {
        List<UserDTO> userDTOList = new ArrayList<>();
        List<User> userList = userService.list();
        if (userList != null) {
            UserDTO userDTO;
            for (User user : userList) {
                userDTO = new UserDTO();
                BeanUtils.copyProperties(user, userDTO);
                userDTOList.add(userDTO);
            }
        }
        return userDTOList;
    }

    @GetMapping("/get")
    public UserDTO get(UserDTO userDTO) {
        log.info("call UserController.get(), userDTO = {}", userDTO);
        if (userDTO == null) {
            return null;
        }

        User user = userService.getById(userDTO.getId());
        if (user == null) {
            return null;
        }

        userDTO = new UserDTO();
        BeanUtils.copyProperties(user, userDTO);

        return userDTO;
    }

    @PostMapping("/save")
    public boolean save(UserDTO userDTO) {
        log.info("call UserController.save(), userDTO = {}", userDTO);
        if (userDTO == null) {
            return false;
        }

        User user = new User();
        user.setId(System.currentTimeMillis());
        user.setUsername(userDTO.getUsername());
        user.setPassword(MD5Utils.md5(userDTO.getPassword()));
        user.setNickname(userDTO.getNickname());
        user.setSex(userDTO.getSex());
        user.setAge(userDTO.getAge());
        user.setMobile(userDTO.getMobile());
        user.setEmail(userDTO.getEmail());
        user.setCreateTime(System.currentTimeMillis());

        return userService.save(user);
    }

    /**
     * 读取配置服务器的“user.info”信息。
     */
    @GetMapping("/info")
    public String getInfo() {
        return "UserServiceConfig[user.info]: " + info;
    }

}
